using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Net;
using System.Web;

using DirectShowLib;

using IGlobalist.LectureService;
using IGlobalist.Net.Rtp;
namespace IGlobalist
{
    public class Global
    {
        public static FrmMain MainForm;
        public static Service Svc;
        public static IPAddress LocalIPAddress = null;
        public static bool ServiceStarted = false;
        public static RtpSession RtpSession;
        public static SessionSettings Settings;
        public static ClientDescription SourceDescription = null;
        public static CastServiceDescription CastServiceDescription = null;
        public static bool HasAudioInput = false;
        public static bool HasVideoInput = false;
        public static string VideoInputDeviceName = "";
        public static string AudioInputDeviceName = "";
        public static string VideoCompressorName = "Microsoft Windows Media Video 9";
        public static string AudioCompressorName = "DSP Group TrueSpeech(TM)";
        //Virginia tech [Capture Monitor Screen Filter]
        public static Guid DesktopCaptureGuid = new Guid("64290030-E89E-43F7-9E12-E359AD17CE5E");
        //=====================================================================
        static Global()
        {
            Svc = new Service();
            CookieContainer cc = new CookieContainer();
            Svc.CookieContainer = cc;
        }


        public static IBaseFilter GetVideoCompressor()
        {
            return CreateFilter(FilterCategory.VideoCompressorCategory, VideoCompressorName);
        }
        public static IBaseFilter GetAudioCompressor()
        {
            return CreateFilter(FilterCategory.AudioCompressorCategory, AudioCompressorName);
        }
        public static IBaseFilter GetVideoInput()
        {
            return CreateFilter(FilterCategory.VideoInputDevice, VideoInputDeviceName);
        }
        public static IBaseFilter GetAudioInput()
        {
            return CreateFilter(FilterCategory.AudioInputDevice, AudioInputDeviceName);
        }
        public static IBaseFilter GetDesktopInput()
        {
            return CreateFilterByGuid(DesktopCaptureGuid);
        }

        public static IBaseFilter CreateFilter(Guid category, string friendlyname)
        {
            object source = null;
            Guid iid = typeof(IBaseFilter).GUID;
            foreach (DsDevice device in DsDevice.GetDevicesOfCat(category))
            {
                if (device.Name.CompareTo(friendlyname) == 0)
                {
                    device.Mon.BindToObject(null, null, ref iid, out source);
                    break;
                }
            }

            return (IBaseFilter)source;
        }
        public static IBaseFilter CreateFilterByGuid(Guid clsid)
        {
            IBaseFilter filter = null;

          
            try
            {
                Type type = Type.GetTypeFromCLSID(clsid);
                filter = (IBaseFilter)Activator.CreateInstance(type);
            }
            catch
            {
                if (filter != null)
                {
                    Marshal.ReleaseComObject(filter);
                    filter = null;
                }
            }

            return filter;

        }

        /// <summary>
        /// Displays a property page for a filter
        /// </summary>
        /// <param name="dev">The filter for which to display a property page</param>
        public static void DisplayPropertyPage(IBaseFilter dev)
        {
            //Get the ISpecifyPropertyPages for the filter
            ISpecifyPropertyPages pProp = dev as ISpecifyPropertyPages;
            int hr = 0;

            if (pProp == null)
            {
                //If the filter doesn't implement ISpecifyPropertyPages, try displaying IAMVfwCompressDialogs instead!
                IAMVfwCompressDialogs compressDialog = dev as IAMVfwCompressDialogs;
                if (compressDialog != null)
                {

                    hr = compressDialog.ShowDialog(VfwCompressDialogs.Config, IntPtr.Zero);
                    DsError.ThrowExceptionForHR(hr);
                }
                return;
            }

            //Get the name of the filter from the FilterInfo struct
            FilterInfo filterInfo;
            hr = dev.QueryFilterInfo(out filterInfo);
            DsError.ThrowExceptionForHR(hr);

            // Get the propertypages from the property bag
            DsCAUUID caGUID;
            hr = pProp.GetPages(out caGUID);
            DsError.ThrowExceptionForHR(hr);

            // Check for property pages on the output pin
            IPin pPin = DsFindPin.ByDirection(dev, PinDirection.Output, 0);
            ISpecifyPropertyPages pProp2 = pPin as ISpecifyPropertyPages;
            if (pProp2 != null)
            {
                DsCAUUID caGUID2;
                hr = pProp2.GetPages(out caGUID2);
                DsError.ThrowExceptionForHR(hr);

                if (caGUID2.cElems > 0)
                {
                    int soGuid = Marshal.SizeOf(typeof(Guid));

                    // Create a new buffer to hold all the GUIDs
                    IntPtr p1 = Marshal.AllocCoTaskMem((caGUID.cElems + caGUID2.cElems) * soGuid);

                    // Copy over the pages from the Filter
                    for (int x = 0; x < caGUID.cElems * soGuid; x++)
                    {
                        Marshal.WriteByte(p1, x, Marshal.ReadByte(caGUID.pElems, x));
                    }

                    // Add the pages from the pin
                    for (int x = 0; x < caGUID2.cElems * soGuid; x++)
                    {
                        Marshal.WriteByte(p1, x + (caGUID.cElems * soGuid), Marshal.ReadByte(caGUID2.pElems, x));
                    }

                    // Release the old memory
                    Marshal.FreeCoTaskMem(caGUID.pElems);
                    Marshal.FreeCoTaskMem(caGUID2.pElems);

                    // Reset caGUID to include both
                    caGUID.pElems = p1;
                    caGUID.cElems += caGUID2.cElems;
                }
            }

            // Create and display the OlePropertyFrame
            object oDevice = (object)dev;
            hr = OleCreatePropertyFrame(MainForm.Handle, 0, 0, filterInfo.achName, 1, ref oDevice, caGUID.cElems, caGUID.pElems, 0, 0, IntPtr.Zero);
            DsError.ThrowExceptionForHR(hr);

            // Release COM objects
            Marshal.FreeCoTaskMem(caGUID.pElems);
            Marshal.ReleaseComObject(pProp);
            if (filterInfo.pGraph != null)
            {
                Marshal.ReleaseComObject(filterInfo.pGraph);
            }
        }
        [DllImport(@"oleaut32.dll")]
        public static extern int OleCreatePropertyFrame(
            IntPtr hwndOwner,
            int x,
            int y,
            [MarshalAs(UnmanagedType.LPWStr)] string lpszCaption,
            int cObjects,
            [MarshalAs(UnmanagedType.Interface, ArraySubType = UnmanagedType.IUnknown)] 
			ref object ppUnk,
            int cPages,
            IntPtr lpPageClsID,
            int lcid,
            int dwReserved,
            IntPtr lpvReserved);
    }
}
